<template>
  <a-form
    id="RenderForm"
    ref="renderFormRef"
    :model="formModel"
    :disabled="formDisable"
    :size="formConfig.size"
    :layout="formConfig.layout"
    :label-align="formConfig.labelAlign"
    :label-col-props="formConfig.labelColProps"
    :wrapper-col-props="formConfig.wrapperColProps"
  >
    <template v-for="(item, index) in formList" :key="index">
      <template v-if="item.group === 'container'">
        <component
          :is="item.component+'Render'"
          :id="item.id"
          v-model="formModel"
          :item="item"
          :item-config="item.itemConfig"
          :config="item.config"
        />
      </template>
      <template v-else>
        <component
          :is="item.component"
          :id="item.id"
          v-model="formModel[item.id]"
          :item="item"
          :item-config="item.itemConfig"
          :config="item.config"
        />
      </template>
    </template>
  </a-form>
</template>

<script lang="ts" setup>
import { ref, provide, defineModel, defineProps, defineExpose, getCurrentInstance } from 'vue';
import { ValidatedError } from '@arco-design/web-vue';
import { FieldData } from '@arco-design/web-vue/es/form/interface';

const props = defineProps({
  formList: {
    type: Array,
    default: () => []
  },
  formConfig: {
    type: Object,
    default: () => {
      return {};
    }
  },
  formPermission: {
    type: Object,
    default: () => {
      return {};
    }
  },
  formDisable: {
    type: Boolean,
    default: () => false
  }
});

const formModel = defineModel('model', { type: Object, default: {} });

const proxy = getCurrentInstance();

const renderFormRef = ref();

provide('formInstance', proxy);
provide('formType', 'render');
provide('formPermission', props.formPermission || {});

/**
 * 校验部分字段
 * @param field
 * @param successCallBack
 * @param failCallback
 */
const validateField = (field: string | string[], successCallBack?: () => void, failCallback?: () => void) => {
  renderFormRef.value.validateField(field, (errors: undefined | Record<string, ValidatedError>) => {
    if (errors) {
      if (failCallback) {
        failCallback();
      }
      return;
    }
    if (successCallBack) {
      successCallBack();
    }
  });
};
/**
 * 只校验可编辑的字段
 * @param successCallBack
 * @param failCallback
 */
const validateFormField = (successCallBack?: () => void, failCallback?: () => void) => {
  const field: string[] = [];
  Object.keys(props.formPermission).forEach(key => {
    if (props.formPermission[key] === 'E') {
      field.push(key);
    }
  });
  renderFormRef.value.validateField(field, (errors: undefined | Record<string, ValidatedError>) => {
    if (errors) {
      if (failCallback) {
        failCallback();
      }
      return;
    }
    if (successCallBack) {
      successCallBack();
    }
  });
};

/**
 * 校验全部字段
 * @param successCallBack
 * @param failCallback
 */
const validateForm = (successCallBack?: () => void, failCallback?: () => void) => {
  renderFormRef.value.validate((errors: undefined | Record<string, ValidatedError>) => {
    if (errors) {
      if (failCallback) {
        failCallback();
      }
      return;
    }
    if (successCallBack) {
      successCallBack();
    }
  });
};

const resetFields = () => {
  renderFormRef.value.resetFields();
};

const clearValidate = () => {
  renderFormRef.value.clearValidate();
};

const setField = (data: Record<string, FieldData>) => {
  renderFormRef.value.setFields(data);
};

const scrollToField = (field: string) => {
  renderFormRef.value.scrollToField(field);
};

defineExpose({
  setField,
  validateField,
  scrollToField,
  validateForm,
  validateFormField,
  clearValidate,
  resetFields
});
</script>

<script lang="ts">
export default {
  name: 'FormRender'
};
</script>

<style scoped>

</style>